package com.bondex.charter.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bondex.charter.dao.CharterSiMapper;
import com.bondex.charter.po.CharterSi;
import com.bondex.charter.service.TdJsonService;
import com.bondex.charter.service.utils.NumberParser;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.graphics.PdfTrueTypeFont;
import com.spire.pdf.security.PdfCertificate;
import com.spire.pdf.security.PdfCertificationFlags;
import com.spire.pdf.security.PdfSignature;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;

/**
 * Service业务层处理
 *
 * @author dkj
 * @date 2021-09-17
 */
@Service
public class TdJsonServiceImpl implements TdJsonService {

    @Autowired
    private CharterSiMapper charterSiMapper;

    /**
     * 不带签章格式单生成
     */
    @Override
    public File buildCutOff(String orderNo) {
        CharterSi charterSi = charterSiMapper.selectByOrderNo(orderNo);
        Boolean update;
        Map<String, Object> singleMap = null;
        List<Map<String, Object>> multiList = null;
        int level = 1;
        String bString = "";
        if (charterSi != null) {
            update = false;
            singleMap = new HashMap<String, Object>();
            multiList = new ArrayList<Map<String, Object>>();
            if (StringUtils.isNotEmpty(charterSi.getVessel()) && StringUtils.isNotEmpty(charterSi.getVoyage())) {
                String vessel = charterSi.getVessel();
                String voyage = charterSi.getVoyage();
                singleMap.put("Ocean Vessel/Voyage", vessel + "   " + voyage);
            }
            if (StringUtils.isNotEmpty(charterSi.getNotify())) {
                singleMap.put("Notify Party(complete name and address)", charterSi.getNotify());
            }
            if (StringUtils.isNotEmpty(charterSi.getShipper())) {
                singleMap.put("Shipper(complete name and address)", charterSi.getShipper());
            }
            singleMap.put("Gross weight kgs", charterSi.getGrossWeight().doubleValue() + charterSi.getGrossWeightUnit());
            singleMap.put("Measurement m3", charterSi.getVolume().doubleValue() + charterSi.getVolumeUnit());
            if (StringUtils.isNotEmpty(charterSi.getNoOfPackage() + "")) {
                singleMap.put("kind", charterSi.getPackageTypeName());
                singleMap.put("packages", charterSi.getNoOfPackage() + "");
            }
            singleMap.put("SAY TOTAL", NumberParser.parse(charterSi.getNoOfPackage() + "") + charterSi.getPackageTypeName().toUpperCase() + " ONLY.");
            String pinming = charterSi.getDescription();
            if (StringUtils.isNotEmpty(pinming) && pinming.split("/r/n").length > 5) {
                level = 2;
                String[] s2 = pinming.split("/r/n");
                String firstPageContent = "";
                String secondPageContent = "";
                for (int j = 0; j < s2.length; j++) {
                    if (j < 14) {
                        firstPageContent += s2[j] + "/r/n";
                    } else {
                        secondPageContent += s2[j] + "/r/n";
                    }
                }
                singleMap.put("pinming", firstPageContent.replace("\"", "\\\""));
                bString += secondPageContent.replace("\"", "\\\"") + "/r/n";
            }
            if (StringUtils.isNotEmpty(charterSi.getMarksNo())) {
                String[] s = charterSi.getMarksNo().split("/r/n");
                String firstPageContent = "";
                String secondPageContent = "";
                if (s.length >= 15) {
                    level = 2;
                    for (int j = 0; j < s.length; j++) {
                        if (j < 15) {
                            firstPageContent += s[j] + "/r/n";
                        } else {
                            secondPageContent += s[j] + "/r/n";
                        }
                    }
                    singleMap.put("Marks & Nos/Container Nos", firstPageContent.replace("\"", "\\\""));
                    singleMap.put("a", secondPageContent.replace("\"", "\\\""));
                } else {
                    singleMap.put("Marks & Nos/Container Nos", charterSi.getMarksNo().replace("\"", "\\\""));
                }
            }
            if (StringUtils.isNotEmpty(charterSi.getBlNo())) {
                String blNo = charterSi.getBlNo();
                singleMap.put("B/L No.", blNo);
            }
            if (StringUtils.isNotEmpty(charterSi.getPlaceOfPayName())) {
                singleMap.put("Freight payable at", charterSi.getPlaceOfPayName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPortOfLoadingName())) {
                singleMap.put("Port of Loading", charterSi.getPortOfLoadingName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPlaceOfReceiptName())) {
                singleMap.put("Place of Receipt by Pre - carrier", charterSi.getPlaceOfReceiptName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPortOfDischargeName())) {
                singleMap.put("Port of Discharge", charterSi.getPortOfDischargeName());
            }
            if (StringUtils.isNotEmpty(charterSi.getBlIssuePlaceName())) {
                singleMap.put("Place of B(s)/L Issue", charterSi.getBlIssuePlaceName());
            }
            if (StringUtils.isNotEmpty(charterSi.getContainerInfo().toString())) {
                JSONArray jsonArray = JSONArray.parseArray(charterSi.getContainerInfo().toString());
                if (jsonArray.size() > 2) {
                    level = 2;
                }
                for (int j = 0; j < jsonArray.size(); j++) {
                    JSONObject jsonObject2 = JSON.parseObject(jsonArray.get(j).toString());
                    Object t1 = jsonObject2.get("containerNo");
                    Object t5 = jsonObject2.get("sealNo");
                    Object t9 = jsonObject2.get("containerType");
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("FXT", t1 + "/" + t5 + "/" + t9 + "(SOC)");
                    Object t2 = jsonObject2.get("packageQty");
                    if (t2 != null && jsonObject2.get("packageUnit") != null) {
                        map.put("package", t2.toString().replace(".0", "") + " " + jsonObject2.get("packageUnit"));
                    }
                    Object t3 = jsonObject2.get("weight");
                    if(t3 != null){
                        map.put("weight", t3 + "KGS");
                    }
                    Object t4 = jsonObject2.get("volume");
                    if(t4 != null){
                        map.put("volumn", t4 + "CBM");
                    }
                    multiList.add(j, map);
                }
            }
        }
        if (StringUtils.isNotEmpty(charterSi.getBillRemark()) && level != 2) {
            singleMap.put("description", charterSi.getBillRemark());
        } else if (StringUtils.isNotEmpty(charterSi.getBillRemark()) && level == 2) {
            bString += charterSi.getBillRemark() + "/r/n";
        }
        if (level != 2) {
            singleMap.put("PrepatdCollectRef01", "SHIPPER'S LOAD COUNT&SEAL.");

            if (StringUtils.isNotEmpty(charterSi.getPaymentMethodName())) {
                singleMap.put("PrepatdCollectIndicatorValue", charterSi.getPaymentMethodName());
            }
            if (StringUtils.isNotEmpty(charterSi.getDeliveryTermName())) {
                singleMap.put("PrepatdCollectRef02", charterSi.getDeliveryTermName());
            }
        } else {
            bString += "SHIPPER'S LOAD COUNT&SEAL." + "/r/n/r/n";

            if (StringUtils.isNotEmpty(charterSi.getPaymentMethodName())) {
                bString += charterSi.getPaymentMethodName() + "/r/n/r/n";
            }
            if (StringUtils.isNotEmpty(charterSi.getDeliveryTermName())) {
                bString += charterSi.getDeliveryTermName() + "/r/n/r/n";
            }
        }
        if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length <= 5 && level != 2) {
            singleMap.put("pinming", charterSi.getDescription().replace("\"", "\\\""));
        } else if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length > 5 && level == 2) {
            singleMap.put("b", bString);
        } else if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length <= 5 && level == 2) {
            singleMap.put("pinming", charterSi.getDescription().replace("\"", "\\\"") + "/r/n/r/n" + bString);
        }
        if (StringUtils.isNotEmpty(charterSi.getConsignee())) {
            singleMap.put("Consignee", charterSi.getConsignee());
        }

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = null;
        Boolean bol = true;
        if ("Sea WayBill".equals(charterSi.getDocumentTypeName()) || "710".equals(charterSi.getDocumentTypeCode())) {
            bol = false;
        }
        if (level == 1 && bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC6.cpt&format=pdf");
            update = true;
        } else if (level == 2 && bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC5.cpt&format=pdf");
            update = true;
        } else if (level == 1 && !bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC3.cpt&format=pdf");
            update = true;
        } else if (level == 2 && !bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC4.cpt&format=pdf");
            update = true;
        }
        JSONObject param2 = new JSONObject();
        if (multiList.size() > 0) {
            JSONArray array = JSONArray.parseArray(JSON.toJSONString(multiList));
            param2.put("value2", array);
        }

        param2.put("value", "[" + new JSONObject(singleMap) + "]");

        StringEntity stringEntity = null;
        File tempFile = null;
        try {
            stringEntity = new StringEntity(param2.toString());
            httpPost.setEntity(stringEntity);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000).setConnectionRequestTimeout(5000)
                    .setSocketTimeout(15000).build();
            httpPost.setConfig(requestConfig);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                tempFile = File.createTempFile(charterSi.getBlNo(), "." + "pdf");
                if (tempFile != null) {
                    Boolean flag = tempFile.delete();
                    if (!flag) {
                        //throw new BusinessException("删除报表临时文件失败");
                    }
                }
                byte[] result = EntityUtils.toByteArray(response.getEntity());
                FileCopyUtils.copy(result, new FileOutputStream(tempFile));
                textSignature(tempFile.getPath());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tempFile;
    }

    /**
     * 带签章提单生成
     */
    @Override
    public File formalCutOff(String orderNo) {
        CharterSi charterSi = charterSiMapper.selectByOrderNo(orderNo);
        Boolean update;
        Map<String, Object> singleMap = null;
        List<Map<String, Object>> multiList = null;
        int level = 1;
        String bString = "";
        if (charterSi != null) {
            update = false;
            singleMap = new HashMap<String, Object>();
            multiList = new ArrayList<Map<String, Object>>();
            if (StringUtils.isNotEmpty(charterSi.getVessel()) && StringUtils.isNotEmpty(charterSi.getVoyage())) {
                String vessel = charterSi.getVessel();
                String voyage = charterSi.getVoyage();
                singleMap.put("Ocean Vessel/Voyage", vessel + "   " + voyage);
            }
            if (StringUtils.isNotEmpty(charterSi.getNotify())) {
                singleMap.put("Notify Party(complete name and address)", charterSi.getNotify());
            }
            if (StringUtils.isNotEmpty(charterSi.getShipper())) {
                singleMap.put("Shipper(complete name and address)", charterSi.getShipper());
            }
            singleMap.put("Gross weight kgs", charterSi.getGrossWeight().doubleValue() + charterSi.getGrossWeightUnit());
            singleMap.put("Measurement m3", charterSi.getVolume().doubleValue() + charterSi.getVolumeUnit());
            if (StringUtils.isNotEmpty(charterSi.getNoOfPackage() + "")) {
                singleMap.put("kind", charterSi.getPackageTypeName());
                singleMap.put("packages", charterSi.getNoOfPackage() + "");
            }
            singleMap.put("SAY TOTAL", NumberParser.parse(charterSi.getNoOfPackage() + "") + charterSi.getPackageTypeName().toUpperCase() + " ONLY.");
            String pinming = charterSi.getDescription();
            if (StringUtils.isNotEmpty(pinming) && pinming.split("/r/n").length > 5) {
                level = 2;
                String[] s2 = pinming.split("/r/n");
                String firstPageContent = "";
                String secondPageContent = "";
                for (int j = 0; j < s2.length; j++) {
                    if (j < 14) {
                        firstPageContent += s2[j] + "/r/n";
                    } else {
                        secondPageContent += s2[j] + "/r/n";
                    }
                }
                singleMap.put("pinming", firstPageContent.replace("\"", "\\\""));
                bString += secondPageContent.replace("\"", "\\\"") + "/r/n";
            }
            if (StringUtils.isNotEmpty(charterSi.getMarksNo())) {
                String[] s = charterSi.getMarksNo().split("/r/n");
                String firstPageContent = "";
                String secondPageContent = "";
                if (s.length >= 15) {
                    level = 2;
                    for (int j = 0; j < s.length; j++) {
                        if (j < 15) {
                            firstPageContent += s[j] + "/r/n";
                        } else {
                            secondPageContent += s[j] + "/r/n";
                        }
                    }
                    singleMap.put("Marks & Nos/Container Nos", firstPageContent.replace("\"", "\\\""));
                    singleMap.put("a", secondPageContent.replace("\"", "\\\""));
                } else {
                    singleMap.put("Marks & Nos/Container Nos", charterSi.getMarksNo().replace("\"", "\\\""));
                }
            }
            if (StringUtils.isNotEmpty(charterSi.getBlNo())) {
                String blNo = charterSi.getBlNo();
                singleMap.put("B/L No.", blNo);
            }
            if (StringUtils.isNotEmpty(charterSi.getPlaceOfPayName())) {
                singleMap.put("Freight payable at", charterSi.getPlaceOfPayName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPortOfLoadingName())) {
                singleMap.put("Port of Loading", charterSi.getPortOfLoadingName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPlaceOfReceiptName())) {
                singleMap.put("Place of Receipt by Pre - carrier", charterSi.getPlaceOfReceiptName());
            }
            if (StringUtils.isNotEmpty(charterSi.getPortOfDischargeName())) {
                singleMap.put("Port of Discharge", charterSi.getPortOfDischargeName());
            }
            if (StringUtils.isNotEmpty(charterSi.getBlIssuePlaceName())) {
                singleMap.put("Place of B(s)/L Issue", charterSi.getBlIssuePlaceName());
            }
            if (StringUtils.isNotEmpty(charterSi.getContainerInfo().toString())) {
                JSONArray jsonArray = JSONArray.parseArray(charterSi.getContainerInfo().toString());
                if (jsonArray.size() > 2) {
                    level = 2;
                }
                for (int j = 0; j < jsonArray.size(); j++) {
                    JSONObject jsonObject2 = JSON.parseObject(jsonArray.get(j).toString());
                    Object t1 = jsonObject2.get("containerNo");
                    Object t5 = jsonObject2.get("sealNo");
                    Object t9 = jsonObject2.get("containerType");
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("FXT", t1 + "/" + t5 + "/" + t9 + "(SOC)");
                    Object t2 = jsonObject2.get("packageQty");
                    if (t2 != null && jsonObject2.get("packageUnit") != null) {
                        map.put("package", t2.toString().replace(".0", "") + " " + jsonObject2.get("packageUnit"));
                    }
                    Object t3 = jsonObject2.get("weight");
                    if(t3 != null){
                        map.put("weight", t3 + "KGS");
                    }
                    Object t4 = jsonObject2.get("volume");
                    if(t4 != null){
                        map.put("volumn", t4 + "CBM");
                    }
                    multiList.add(j, map);
                }
            }
        }
        if (StringUtils.isNotEmpty(charterSi.getBillRemark()) && level != 2) {
            singleMap.put("description", charterSi.getBillRemark());
        } else if (StringUtils.isNotEmpty(charterSi.getBillRemark()) && level == 2) {
            bString += charterSi.getBillRemark() + "/r/n";
        }
        if (level != 2) {
            singleMap.put("PrepatdCollectRef01", "SHIPPER'S LOAD COUNT&SEAL.");

            if (StringUtils.isNotEmpty(charterSi.getPaymentMethodName())) {
                singleMap.put("PrepatdCollectIndicatorValue", charterSi.getPaymentMethodName());
            }
            if (StringUtils.isNotEmpty(charterSi.getDeliveryTermName())) {
                singleMap.put("PrepatdCollectRef02", charterSi.getDeliveryTermName());
            }
        } else {
            bString += "SHIPPER'S LOAD COUNT&SEAL." + "/r/n/r/n";

            if (StringUtils.isNotEmpty(charterSi.getPaymentMethodName())) {
                bString += charterSi.getPaymentMethodName() + "/r/n/r/n";
            }
            if (StringUtils.isNotEmpty(charterSi.getDeliveryTermName())) {
                bString += charterSi.getDeliveryTermName() + "/r/n/r/n";
            }
        }
        if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length <= 5 && level != 2) {
            singleMap.put("pinming", charterSi.getDescription().replace("\"", "\\\""));
        } else if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length > 5 && level == 2) {
            singleMap.put("b", bString);
        } else if (StringUtils.isNotEmpty(charterSi.getDescription()) && charterSi.getDescription().split("/r/n").length <= 5 && level == 2) {
            singleMap.put("pinming", charterSi.getDescription().replace("\"", "\\\"") + "/r/n/r/n" + bString);
        }
        if (StringUtils.isNotEmpty(charterSi.getConsignee())) {

            singleMap.put("Consignee", charterSi.getConsignee());
        }
        if (charterSi.getAtd() != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM.dd,yyyy", Locale.UK);
            singleMap.put("On Board Date", simpleDateFormat.format(charterSi.getAtd()).toUpperCase());
        }

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = null;
        Boolean bol = true;
        if ("Sea WayBill".equals(charterSi.getDocumentTypeName()) || "710".equals(charterSi.getDocumentTypeCode())) {
            bol = false;
        }
        if (level == 1 && bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC10.cpt&format=pdf");
            update = true;
        } else if (level == 2 && bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC9.cpt&format=pdf");
            update = true;
        } else if (level == 1 && !bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC7.cpt&format=pdf");
            update = true;
        } else if (level == 2 && !bol) {
            httpPost = new HttpPost("http://10.0.10.203:8075/webroot/decision/view/report?op=fs_load&cmd=fs_signin&reportKind=load&reportlet=VOCC8.cpt&format=pdf");
            update = true;
        }
        JSONObject param2 = new JSONObject();
        if (multiList.size() > 0) {
            JSONArray array = JSONArray.parseArray(JSON.toJSONString(multiList));
            param2.put("value2", array);
        }
        param2.put("value", "[" + new JSONObject(singleMap) + "]");
        StringEntity stringEntity = null;
        File tempFile = null;
        try {
            stringEntity = new StringEntity(param2.toString());
            httpPost.setEntity(stringEntity);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000).setConnectionRequestTimeout(5000)
                    .setSocketTimeout(15000).build();
            httpPost.setConfig(requestConfig);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                tempFile = File.createTempFile(charterSi.getBlNo(), "." + "pdf");
                if (tempFile != null) {
                    Boolean flag = tempFile.delete();
                    if (!flag) {
                        //throw new BusinessException("删除报表临时文件失败");
                    }
                }
                byte[] result = EntityUtils.toByteArray(response.getEntity());
                FileCopyUtils.copy(result, new FileOutputStream(tempFile));
                textSignature(tempFile.getPath());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tempFile;
    }


    public static void textSignature(String pathname) {
        PdfDocument doc = new PdfDocument(pathname);
        //加载pfx证书
        PdfCertificate cert = new PdfCertificate("charter-business-api/src/main/resources/bondex.pfx", "Bondex@1#2$5*34A");
        //添加数字签名，设置其位置和大小
        for (int i = 1; i <= doc.getPages().getCount(); i++) {
            PdfSignature signature = new PdfSignature(doc, doc.getPages().get(doc.getPages().getCount() - i), cert, "MySignature");
            //PdfSignature signature = new PdfSignature();
            Rectangle2D rect = new Rectangle2D.Float();
            rect.setFrame(new Point2D.Float((float) doc.getPages().get(0).getActualSize().getWidth() - 270, (float) doc.getPages().get(0).getActualSize().getHeight() - 200), new Dimension(50, 50));
            signature.setBounds(rect);
            //设置签名的字体
            signature.setSignDetailsFont(new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, 0)));
            //设置文档权限为禁止更改
            signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);
            signature.setCertificated(true);
        }
        //保存文档
        doc.saveToFile(pathname);
        doc.close();
    }

}
